﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using KTool2.Common;
using System.Runtime.Serialization.Formatters.Binary;
using KTool2.CustomEvent;
using KTool2.Exceptions;

namespace KTool2.Utility
{
    /// <summary>
    /// Class for application setting operations
    /// </summary>
    [Serializable]
    public class AppSetting
    {
        private TimeSpan meanTime;
        private string category;
        private bool[] rateShowingArray;
        private bool autoStart;
        private bool keepTranslation;
        public delegate void SettingChangeEventHandler(object sender, SettingEventArgs e);
        [field:NonSerialized]
        public event SettingChangeEventHandler SettingChanged;
        [field: NonSerialized]
        private static AppSetting instance;

        public static AppSetting Instance
        {
            get 
            {
                if (instance == null)
                {
                    instance = new AppSetting();
                }

                return instance; 
            }
        }

        /// <summary>
        /// Time for a text to show itself
        /// </summary>
        public bool AutoStart
        {
            get { return autoStart; }
            set 
            {
                autoStart = value;
                SettingChanged(this, new SettingEventArgs(AppProperties.AUTO_START));
            }
        }

        /// <summary>
        /// Table name or sheet nam in the database
        /// </summary>
        public bool[] RateShowingArray
        {
            get { return rateShowingArray; }
            set 
            {
                rateShowingArray = value;
                SettingChanged(this, new SettingEventArgs(AppProperties.RATE_SHOWING_ARRAY));
            }
        }

        /// <summary>
        /// Category (table or sheet)
        /// </summary>
        public string Category
        {
            get { return category; }
            set 
            {
                category = value;
                SettingChanged(this, new SettingEventArgs(AppProperties.CATEGORY));
            }
        }

        /// <summary>
        /// Is the program auto start or not
        /// </summary>
        public TimeSpan MeanTime
        {
            get { return meanTime; }
            set 
            { 
                meanTime = value;
                SettingChanged(this, new SettingEventArgs(AppProperties.TEXT_CHANGE_TIME));
            }
        }

        public bool KeepTranslation 
        {
            get { return keepTranslation; }
            set
            {
                keepTranslation = value;
                SettingChanged(this, new SettingEventArgs(AppProperties.KEEP_TRANSLATION));
            }
        }

        public static void SaveSetting(AppSetting settings)
        {
            if (!Directory.Exists(Constant.APP_FOLDER))
            {
                Directory.CreateDirectory(Constant.APP_FOLDER);
            }

            try
            {
                using (Stream fStream = new FileStream(Constant.SETTING_FILE_PATH, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    new BinaryFormatter().Serialize(fStream, settings);
                }
            }
            catch (Exception e)
            {
                throw new ApplicationException("Error while saving settings!\n"
                    + e.Message);
            }
        }

        public static void LoadLastSetting()
        {
            if (Directory.Exists(Constant.APP_FOLDER))
            {
                using (Stream fStream = new FileStream(Constant.SETTING_FILE_PATH, FileMode.Open))
                {
                    instance = (AppSetting)new BinaryFormatter().Deserialize(fStream);

                    if (!Instance.IsValid)
                    {
                        throw new ApplicationSettingException(1, null);
                    }
                }
            }
            else
            {
                LoadDefaultSetting();
            }

            //return Instance;
        }

        public static void LoadDefaultSetting()
        {
            Instance.autoStart = true;
            Instance.category = Constant.ALL_CATEGORIES;
            Instance.meanTime = TimeSpan.FromSeconds(30);
            Instance.rateShowingArray = new Boolean[5];
            Instance.rateShowingArray[0] = true;
            Instance.rateShowingArray[1] = true;
            Instance.keepTranslation = true;

            //return Instance;
        }

        public AppSetting()
        {
            // Hide default constructor
        }

        public bool IsValid
        {
            get
            {
                if (this.rateShowingArray == null 
                    || this.meanTime == null || this.meanTime.Seconds <= 0
                    || string.IsNullOrEmpty(this.category) 
                    || this.autoStart == null 
                    || this.keepTranslation == null)
                {
                    return false;
                }

                return true;
            }
        }
    }
}
